<template>
  <div class="hello">
    <canvas id="canvas" v-show="true" style="border:1px solid gray;width:100%;height:20rem;"></canvas>
    <div style="margin-top: 1rem"></div>
    <div>
      <input v-model="expression" @input="draw" style="padding: 8px;font-size:20px;width:80%;" placeholder="sin(x)">
    </div>
    <!-- <button @click="draw">绘图</button> -->
   <!-- <div> {{msg}} </div> -->
    <div style="margin-top: 1rem"></div>
    <div>
      <input v-model="scale_x" type="range" min="10" max="100" @change="draw()" style="width:24rem">
      <button @click="scale_x=10;draw();">重置</button>
    </div>
    <div>x轴缩放{{scale_x}}</div>
    <div>
      <input v-model="scale_y" type="range" min="10" max="100" @change="draw()" style="width:24rem">
      <button @click="scale_y=10;draw();">重置</button>
    </div>
    <div>y轴缩放{{scale_y}}</div>
  </div>
</template>

<script>

import Calculator from '@/utils/core'

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: '',
      expression: 'sin(x)',
      calcer: new Calculator(),
      ctx : null,
      cvs : null,
      xx : -50,
      yy : 50,
      scale: 100,
      scale_x: 20,
      scale_y: 20,
      t: 0
    }
  },
  created() {
    this.calc();
    let that = this;
    setTimeout(() => {
      let cvs = document.querySelector('#canvas');
      this.cvs = cvs;
      let ctx = cvs.getContext("2d");
      this.ctx = ctx;

      // start
      this.xx = cvs.width / 2;
      this.yy = cvs.height / 2;
      this.draw();

      let old_x = 0, old_y = 0, touching = false;

      cvs.addEventListener("touchstart", handleMouseDown, false);
      cvs.addEventListener("mousedown", handleMouseDown, false);

      cvs.addEventListener("touchmove", handleMouseMove, false);
      cvs.addEventListener("mousemove", handleMouseMove, false);

      cvs.addEventListener("touchend", handleMouseUp, false);
      cvs.addEventListener("mouseup", handleMouseUp, false);


      cvs.addEventListener('mousewheel', function(e) {
          e.preventDefault();
          var wheel = e.wheelDelta || -e.detail;
          var delta = Math.max(-1, Math.min(1, wheel) );
          if (delta < 0){
              that.scale_x *= 0.98;
              that.scale_y *= 0.98;
          } else {
              that.scale_x *= 1.02;
              that.scale_y *= 1.02;
          }
          that.draw();
      });

      function handleMouseDown(e) {
        touching = true;
        var touch = e.touches ? e.touches[0] : e;
        let touchx = touch.clientX;
        let touchy = touch.clientY;
        old_x = touchx;
        old_y = touchy;
      }

      function handleMouseMove(e) {
        if (touching == false) return;
        var touch = e.touches ? e.touches[0] : e;
        let touchx = touch.clientX;
        let touchy = touch.clientY;
        let dx = touchx - old_x;
        let dy = touchy - old_y;
        that.xx += dx;
        that.yy += dy;
        old_x = touchx;
        old_y = touchy;
        that.draw();
      }

      function handleMouseUp(e) {
        touching = false;
      }

    });
  },
  methods: {
    calc() {
      let result = this.calcer.calc(this.expression);
      if (result === '') {
        this.msg = '0';
        return;
      }
      this.msg = this.expression + ' = ' + result// + "\n("+eval(this.expression)+")";
    },
    posAryOf(splited, chr) {
      let ary = [];
      for (let i=0;i<splited.length;i++) {
        if (splited[i] == chr) {
          ary.push(i);
        }
      }
      return ary;
    },
    assigns(splited, x_pos_ary, val) {
      for (let i=0;i<x_pos_ary.length;i++) {
        splited[x_pos_ary[i]] = val;
      }
    },
    drawCoordinateSystem(cvs, ctx, scale_x, scale_y) {
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.strokeStyle = 'green';
      let xx = this.xx;
      let yy = this.yy;
      let w = cvs.width;
      let h = cvs.height;
      ctx.moveTo(0, 0 + yy);
      ctx.lineTo(w, 0 + yy);
      ctx.moveTo(0 + xx, 0);
      ctx.lineTo(0 + xx, h);
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      let length = 3;
      let d_per_calibration_x = 1 * scale_x;
      let d_per_calibration_y = 1 * scale_y;

      let distance_x = -xx - Math.floor(-xx / d_per_calibration_x) * d_per_calibration_x;
      for (let x=-distance_x;x < w+distance_x;x+=d_per_calibration_x) {
        ctx.moveTo(x, -length + yy);
        ctx.lineTo(x, length + yy);
      }
      let distance_y = -yy - Math.floor(-yy / d_per_calibration_y) * d_per_calibration_y;
      for (let y=-distance_y;y < h+distance_y;y+=d_per_calibration_y) {
        ctx.moveTo(-length + xx, y);
        ctx.lineTo(length + xx, y);
      }

      ctx.stroke();
      ctx.closePath();
    },

    draw() {
      let exp = this.expression;

      let cvs = this.cvs;
      let ctx = this.ctx;

      let scale_x = this.scale_x;
      let scale_y = this.scale_y;

      let splited_x = this.calcer.splitExpression(exp);
      let x_pos_ary = this.posAryOf(splited_x, 'x');
      this.assigns(splited_x, x_pos_ary, 0);

      ctx.clearRect(0, 0, cvs.width, cvs.height);
      this.drawCoordinateSystem(cvs, ctx, scale_x, scale_y);
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.strokeStyle = 'blue';

      this.assigns(splited_x, x_pos_ary, 0);
      ctx.moveTo(0, -this.calcer.calcExpression(splited_x) * scale_y + this.yy);
      let ans = 0;
      let old_x, old_y;
      for (let x=(0-this.xx);x<(cvs.width-this.xx);x+=0.15) {
        let _x = x / scale_x;
        this.assigns(splited_x, x_pos_ary, _x);
        let _y = -this.calcer.calcExpression(splited_x);
        ctx.lineTo(x + this.xx, _y * scale_y + this.yy);
        old_x = x;
        old_y = _y;

        if (ans ++ == (cvs.width/2/0.15).toFixed()) {
          console.log(ans-1);
          ctx.arc(x + this.xx, _y * scale_y + this.yy, 1, 0, 2*Math.PI);
          ctx.strokeText(" ( "+_x.toFixed(2)+', '+_y.toFixed(2)+" )", x + this.xx, _y * scale_y + this.yy);
          ctx.moveTo(x + this.xx, 0);
          ctx.lineTo(x + this.xx, cvs.height);
          ans = 0;
        }

      }
      ctx.stroke();
      ctx.closePath();
    },

   }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello {
  max-width: 32rem;
  margin: auto;
}
canvas {
  border-radius: 5px;
  box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75);
}
input, button {
  border-radius: 5px;
  padding: 10px;
  font-size: 18px;
}
button {
  background-color: #4CAF50; /* Green */
  border: none;
  color: white;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  transition-duration: 0.4s;
}
button:hover {
  background-color: #45a049;
}
div {
  margin-bottom: 15px;
}
input[type=range] {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;  
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%; 
  background: #4CAF50;
  cursor: pointer;
}

input[type=range]::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4CAF50;
  cursor: pointer;
}


</style>
